package com.gao.f_reactor.b.server;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author gao
 * @time 2020/08/15 21:27:01
 */
public class Reactor implements Runnable {
    private Selector selector;
    private ServerSocketChannel serverSocketChannel;

    public Reactor(ServerSocketChannel serverSocketChannel) throws IOException {
        this.selector = Selector.open();
        this.serverSocketChannel = serverSocketChannel;

        SelectionKey key = this.serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        key.attach(new Acceptor(this.serverSocketChannel, this.selector));
    }

    @Override
    public void run() {
        System.out.println("服务器已开启");
        try {
            while (true) {
                int n = selector.select();
                if (n > 0) {
                    Set<SelectionKey> selectedKeys = selector.selectedKeys();
                    Iterator<SelectionKey> it = selectedKeys.iterator();
                    while (it.hasNext()) {
                        SelectionKey key = it.next();
                        it.remove();
                        dispatch(key);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    void dispatch(SelectionKey key) {
        // 如果事件是“连接事件”，则获取的是Accept对象
        // 如果事件是“IO读/写事件”，则获取的是Handler对象
        Runnable runnable = (Runnable) key.attachment();
        if (runnable != null) {
            runnable.run();
        }
    }

}
